package com.sig.util.id;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author sig
 * @since 2019/1/29
 */
public class SnowflakeHolder {
    private final int appMachineId;
    private final Snowflake GLOBAL_SNOWFLAKE;
    private final Map<String, Snowflake> catalogSnowflakeMap = new ConcurrentHashMap<>();

    public SnowflakeHolder(int appMachineId) {
        this.appMachineId = appMachineId;
        GLOBAL_SNOWFLAKE = new Snowflake(appMachineId);
    }

    public long generateLongId() {
        return GLOBAL_SNOWFLAKE.generateId();
    }

    public long generateLongId(String catalog) {
        if (catalog == null)
            return this.generateLongId();
        return catalogSnowflakeMap.computeIfAbsent(catalog, k -> new Snowflake(appMachineId)).generateId();
    }

    public long timestamp(long id) {
        return (id >> Snowflake.timestampLeftShift) + Snowflake.usingEpoch;
    }

    public int gameServerId(long id) {
        int offset = 64 - Snowflake.timestampLeftShift;
        return (int) (((id << offset) >> offset) >> Snowflake.sequenceBits);
    }

    public int sequence(long id) {
        int offset = 64 - Snowflake.sequenceBits;
        return (int) ((id << offset) >> offset);
    }
}
